package mysql

import (
	"context"
	"data-transfer/conf"
	"data-transfer/domain"
	"data-transfer/global"
	"data-transfer/transfer"
	"encoding/json"
	"fmt"
	"github.com/go-mysql-org/go-mysql/mysql"
	"go.uber.org/zap"
	"os"
	"path"
	"strconv"
)
import "github.com/go-mysql-org/go-mysql/canal"

func (mdb *db) MonitorDataChange(ctx context.Context, handler canal.EventHandler, startFlag string) error {
	//设置EventHandler
	mdb.canal.SetEventHandler(handler)

	//第一次执行
	if transfer.GoCanal_First_Run_Flag == startFlag {
		err := mdb.canal.Run()
		if err != nil {
			return err
		}
	} else {

		binlogSetName := global.GBinlogSetPosition.Name
		binlogSetPos := global.GBinlogSetPosition.Pos
		global.LOG.Info("binlog set position:", zap.String("name", binlogSetName))
		global.LOG.Info("binlog set position:", zap.Int32("pos", int32(binlogSetPos)))

		binlogCacheName := global.GBinlogCachePosition.Name
		binlogCachePos := global.GBinlogCachePosition.Pos
		global.LOG.Info("binlog cache position:", zap.String("name", binlogCacheName))
		global.LOG.Info("binlog cache position:", zap.Uint32("pos", binlogCachePos))

		var position mysql.Position
		var err error
		//手动设置优先
		if binlogSetPos > 0 {
			global.LOG.Info("using binlog set position:", zap.String("name", binlogSetName), zap.Int32("pos", int32(binlogSetPos)))
			position = mysql.Position{Name: binlogSetName, Pos: uint32(binlogSetPos)}
		} else if binlogCachePos > 0 { // 缓存第二优先级
			global.LOG.Info("using binlog cache position:", zap.String("name", binlogCacheName), zap.Int32("pos", int32(binlogCachePos)))
			position = mysql.Position{Name: binlogCacheName, Pos: uint32(binlogCachePos)}
		} else {
			position, err = mdb.canal.GetMasterPos() //最后使用API的GetMasterPos
			global.LOG.Info("using GetMasterPos:", zap.String("name", position.Name), zap.Uint32("pos", position.Pos))
		}

		/*
			pos, err := mdb.canal.GetMasterPos()
			if err != nil {
				return err
			}
			global.LOG.Info("GetMaster Pos:",zap.Any("pos",pos))
		*/

		if err != nil {
			return err
		}
		//global.LOG.Info("GetMaster Pos:",zap.Any("pos",position))

		// Start canal
		err = mdb.canal.RunFrom(position)
		if err != nil {
			return err
		}

	}
	return nil

}

//SyncBinlogPosition 定时同步mysql binlog position信息
func (mdb *db) SyncBinlogPosition() {

	fileName := "binlog_position_cache"
	position, err := mdb.canal.GetMasterPos()
	if err != nil {
		global.LOG.Error("SyncBinlogPosition GetMasterPos has error:", zap.Error(err))
		position = mysql.Position{Name: "ErrorMasterPos", Pos: 0}
	}
	fileAllPath := path.Join(fileName)
	global.LOG.Info("SyncBinlogPosition FilePath", zap.String("path", fileAllPath))
	global.LOG.Info("SyncBinlogPosition GetMasterPos:", zap.String("name", position.Name), zap.Uint32("pos", position.Pos))

	p := conf.Position{
		Name: position.Name,
		Pos:  position.Pos,
	}

	b, err := json.Marshal(p)
	if err != nil {
		global.LOG.Error("Marshal GetMasterPos has error:", zap.Error(err))
		return
	}

	if len(b) > 0 {
		// Finally create the file and write
		f, errf := os.Create(fileAllPath)
		if errf != nil {
			global.LOG.Error("create binlog position cache file error:", zap.Error(err))
			return
		}
		defer f.Close()

		_, err = f.Write(b)
		if err != nil {
			global.LOG.Error("write binlog position cache file error:", zap.Error(err))
			return
		}
	}

}

//GetTqSkBasicInfoBySeCode seCode 获取股票基本信息
func (mdb *db) GetTqSkBasicInfoBySeCode(seCode string) (*domain.TQ_SK_BASICINFO, error) {
	basicInfo := new(domain.TQ_SK_BASICINFO)
	//has, err := mdb.db.Where(" SECODE = ? and SETYPE = ?", seCode, transfer.SETYPE_101).Get(basicInfo)
	has, err := mdb.db.Where(" SECODE = ?", seCode).Get(basicInfo) // SECODE 为业务主键
	if err != nil {
		return nil, err
	}
	if has {
		return basicInfo, nil
	} else {
		return nil, nil
	}
}

// GetTqSkBasicInfoBySymbol 根据symbol 获取股票基本信息,只查询上市状态的有效数据
func (mdb *db) GetTqSkBasicInfoBySymbol(symbol string) (*domain.TQ_SK_BASICINFO, error) {
	var results []*domain.TQ_SK_BASICINFO
	err := mdb.db.NewSession().Where("ISVALID = ? AND SYMBOL = ? AND LISTSTATUS = ? ", "1", symbol, transfer.LISTSTATUS_1).Desc("ID").Find(&results)
	if err != nil {
		return nil, err
	}

	if len(results) > 0 {
		return results[0], nil
	}
	return nil, err
}

// GetTqSkBasicInfoByCompanyCode 根据compCode 获取股票基本信息,只查询上市状态的有效数据
func (mdb *db) GetTqSkBasicInfoByCompanyCode(compCode string) ([]*domain.TQ_SK_BASICINFO, error) {
	/*
		basicInfo := new(domain.TQ_SK_BASICINFO)
		has, err := mdb.db.Where(" COMPCODE = ? and SETYPE = ?", compCode, transfer.SETYPE_101).Get(basicInfo)
		if err != nil {
			return nil, err
		}
		if has {
			return basicInfo, nil
		} else {
			return nil, nil
		}
	*/

	var results []*domain.TQ_SK_BASICINFO
	err := mdb.db.NewSession().Where("ISVALID = ? AND COMPCODE = ? AND LISTSTATUS = ? ", "1", compCode, transfer.LISTSTATUS_1).Find(&results)
	if err != nil {
		return nil, err
	}
	return results, nil
}

// GetSymbolByCompCode 根据compCode取得证券类别,存在相同compCode对应多个symbol的情况，例如 双杰电气（80129235）对应symbol为：430049和300444
func (mdb *db) GetSymbolByCompCode(compCode string) ([]*domain.TQ_SK_BASICINFO, error) {
	var results []*domain.TQ_SK_BASICINFO
	//results, err := mdb.db.Where(" COMPCODE = ? and SETYPE = ?", compCode, transfer.SETYPE_101).Find(&results)
	//只查询上市状态的有效数据
	err := mdb.db.NewSession().Where(" ISVALID = ? AND COMPCODE = ? AND LISTSTATUS = ?", "1", compCode, transfer.LISTSTATUS_1).Find(&results)
	if err != nil {
		return nil, err
	}

	/*
		var arr []string
		for _, r := range results {
			symbol := r.Symbol
			arr = append(arr, symbol)
		}
	*/
	return results, nil
}

// GetCompCodeBySymbol 根据symbol取得compCode,默认取国内A股：101
func (mdb *db) GetCompCodeBySymbol(symbol string) (string, error) {
	basicInfo := new(domain.TQ_SK_BASICINFO)
	has, err := mdb.db.Where(" SYMBOL = ? and SETYPE = ?", symbol, transfer.SETYPE_101).Get(basicInfo)
	if err != nil {
		return "", err
	}
	if has {
		return basicInfo.Compcode, nil
	} else {
		return "", nil
	}
}

// GetFileLinkByAnnouncemtId 根据announcementId 获取PDF文件路径
func (mdb *db) GetFileLinkByAnnouncemtId(announcemtId string) (string, error) {

	aid, err := strconv.Atoi(announcemtId)
	if err != nil {
		global.LOG.Error("参数announcemtId有误:", zap.Any("err", err))
		aid = 0
	}

	result := new(domain.TQ_OA_ANNTFILE_DLFC)
	has, err := mdb.db.NewSession().Where("RELATABLE = ? and RELAID = ?", transfer.ANNTFILE_TQ_SK_ANNOUNCEMT, aid).Get(result)
	if err != nil {
		return "", err
	}
	if has {
		return result.Filelink, nil
	} else {
		return "", err
	}

}

//GetSymbolByTrCode 根据trCode获取T_QNEWS_ANIMPM表中的symbol
func (mdb *db) GetSymbolByTrCode(trCode string) (string, error) {

	var results []*domain.T_QNEWS_ANIMPM
	err := mdb.db.NewSession().Where("ISVALID=?  and TRCODE= ?", 1, trCode).Desc("ID").Find(&results)
	if err != nil {
		return "", err
	}

	if len(results) > 0 {
		return results[0].Symbol, nil
	}
	return "", nil

}

//GetSymbolBySourceKey 根据sourceKey获取T_QNEWS_ANIMPM表中的symbol
func (mdb *db) GetSymbolBySourceKey(sourceKey string) (string, error) {
	var results []*domain.T_QNEWS_ANIMPM

	err := mdb.db.NewSession().Where("ISVALID=?  and SOURCEKEY= ?", 1, sourceKey).Desc("ID").Find(&results)
	if err != nil {
		return "", err
	}

	if len(results) > 0 {
		return results[0].Symbol, nil
	}
	return "", nil
}

//GetStdRatingCountsBySymbolAndRatingValid 根据symbol和评级有效期获取评级机构统计对象
func (mdb *db) GetStdRatingCountsBySymbolAndRatingValid(symbol string, ratingValid string) (*domain.RATING_COUNT, error) {

	var err error
	r := new(domain.RATING_COUNT)

	r.Symbol = symbol           //证券代码
	r.Ratingvalid = ratingValid //评级有效期

	compCode, _ := mdb.GetCompCodeBySymbol(symbol)
	r.Compcode = compCode //机构代码

	//Buy
	buy := 0
	buyCnts, err := mdb.db.Query("SELECT COUNT(DISTINCT COMPNAME) CNT  FROM TQ_EXPT_SKINVRATING WHERE ISVALID=? and SYMBOL= ? and STDRATING= ?  AND RATINGVALID = ? GROUP BY STDRATING", "1", symbol, transfer.STDRATING_BUY, ratingValid)
	if err != nil {
		global.LOG.Error("goCanal监控：获取相关标准评级和评级有效期的机构个数出错:", zap.String("stdRating", transfer.STDRATING_BUY), zap.String("ratingValid", ratingValid), zap.Any("err", err))
	}
	for _, v := range buyCnts {
		buy, err = strconv.Atoi(fmt.Sprintf("%s", v["CNT"]))
		if err != nil {
			buy = 0
		}
	}
	r.Buy = buy //评级为买入的机构数

	//ENLARGE
	enlarge := 0
	enlargeCnts, err := mdb.db.Query("SELECT COUNT(DISTINCT COMPNAME) CNT  FROM TQ_EXPT_SKINVRATING WHERE ISVALID=? and SYMBOL= ? and STDRATING= ?  AND RATINGVALID = ? GROUP BY STDRATING", "1", symbol, transfer.STDRATING_ENLARGE, ratingValid)
	if err != nil {
		global.LOG.Error("goCanal监控：获取相关标准评级和评级有效期的机构个数出错:", zap.String("stdRating", transfer.STDRATING_ENLARGE), zap.String("ratingValid", ratingValid), zap.Any("err", err))

	}
	for _, v := range enlargeCnts {
		enlarge, err = strconv.Atoi(fmt.Sprintf("%s", v["CNT"]))
		if err != nil {
			enlarge = 0
		}
	}
	r.Enlarge = enlarge //评级为增持的机构数

	//NEUTRAL
	neutral := 0
	neutralCnts, err := mdb.db.Query("SELECT COUNT(DISTINCT COMPNAME) CNT  FROM TQ_EXPT_SKINVRATING WHERE ISVALID=? and SYMBOL= ? and STDRATING= ?  AND RATINGVALID = ? GROUP BY STDRATING", "1", symbol, transfer.STDRATING_NEUTRAL, ratingValid)
	if err != nil {
		global.LOG.Error("goCanal监控：获取相关标准评级和评级有效期的机构个数出错:", zap.String("stdRating", transfer.STDRATING_NEUTRAL), zap.String("ratingValid", ratingValid), zap.Any("err", err))

	}
	for _, v := range neutralCnts {
		neutral, err = strconv.Atoi(fmt.Sprintf("%s", v["CNT"]))
		if err != nil {
			neutral = 0
		}
	}
	r.Neutral = neutral // 评级为中性的机构数

	//REDUCE
	reduce := 0
	reduceCnts, err := mdb.db.Query("SELECT COUNT(DISTINCT COMPNAME) CNT  FROM TQ_EXPT_SKINVRATING WHERE ISVALID=? and SYMBOL= ? and STDRATING= ?  AND RATINGVALID = ? GROUP BY STDRATING", "1", symbol, transfer.STDRATING_REDUCE, ratingValid)
	if err != nil {
		global.LOG.Error("goCanal监控：获取相关标准评级和评级有效期的机构个数出错:", zap.String("stdRating", transfer.STDRATING_REDUCE), zap.String("ratingValid", ratingValid), zap.Any("err", err))

	}
	for _, v := range reduceCnts {
		reduce, err = strconv.Atoi(fmt.Sprintf("%s", v["CNT"]))
		if err != nil {
			reduce = 0
		}
	}
	r.Reduce = reduce // 评级为减持的机构数

	//SELL
	sell := 0
	sellCnts, err := mdb.db.Query("SELECT COUNT(DISTINCT COMPNAME) CNT  FROM TQ_EXPT_SKINVRATING WHERE ISVALID=? and SYMBOL= ? and STDRATING= ?  AND RATINGVALID = ? GROUP BY STDRATING", "1", symbol, transfer.STDRATING_SELL, ratingValid)
	if err != nil {
		global.LOG.Error("goCanal监控：获取相关标准评级和评级有效期的机构个数出错:", zap.String("stdRating", transfer.STDRATING_SELL), zap.String("ratingValid", ratingValid), zap.Any("err", err))

	}
	for _, v := range sellCnts {
		sell, err = strconv.Atoi(fmt.Sprintf("%s", v["CNT"]))
		if err != nil {
			sell = 0
		}
	}
	r.Sell = sell // 评级为卖出的机构数

	return r, err
}

// GetPersonRecordByPersonalCode 根据 personalCode 获取个人档案信息
func (mdb *db) GetPersonRecordByPersonalCode(personalCode string) (*domain.TQ_COMP_PERSONRECORD, error) {
	var results []*domain.TQ_COMP_PERSONRECORD
	err := mdb.db.NewSession().Where("ISVALID=?  and PERSONALCODE= ?", 1, personalCode).Desc("ID").Find(&results)
	if err != nil {
		return nil, err
	}
	if len(results) > 0 {
		return results[0], nil
	}
	return nil, err
}

//GetCompManagerByPersonalCode 根据  personalCode 获取公司高管入职和辞职等信息
func (mdb *db) GetCompManagerByPersonalCode(personalCode string) (*domain.TQ_COMP_MANAGER, error) {
	var results []*domain.TQ_COMP_MANAGER
	err := mdb.db.NewSession().Where("ISVALID=?  and PERSONALCODE= ?", 1, personalCode).Desc("ID").Find(&results)
	if err != nil {
		return nil, err
	}
	if len(results) > 0 {
		return results[0], nil
	}
	return nil, err
}

//GetTqSkBusiInfoByCompCodeAndReportYear 根据compCode和reportYear 获取公司经营状况
func (mdb *db) GetTqSkBusiInfoByCompCodeAndReportYear(compCode string, reportYear string) ([]*domain.TQ_SK_BUSIINFO, error) {
	var results []*domain.TQ_SK_BUSIINFO
	//只查询分类口径为产品的
	err := mdb.db.NewSession().Where("ISVALID=? and COMPCODE = ? and LEFT(PUBLISHDATE,4)=? and TYPESTYLE=?", 1, compCode, reportYear, transfer.TYPE_STYLE_PRODUCT).Desc("ID").Find(&results)
	return results, err
}

//GetTqFinPrgIncStatementNewByCompCodeAndReportYear 查询指定会计年度、报表类型为1合并期末的企业利润信息
func (mdb *db) GetTqFinPrgIncStatementNewByCompCodeAndReportYear(compCode string, reportYear string) ([]*domain.TQ_FIN_PRGINCSTATEMENTNEW, error) {
	var results []*domain.TQ_FIN_PRGINCSTATEMENTNEW
	//err := mdb.db.NewSession().Where("ISVALID=?  and COMPCODE= ? and REPORTTYPE = ? and REPORTYEAR = ? and REPORTDATETYPE = ?", 1, compCode, transfer.REPORTTYPE_1, reportYear, "4").Desc("ID").Find(&results)
	err := mdb.db.NewSession().Where("ISVALID=?  and COMPCODE= ? and REPORTTYPE = ? and REPORTYEAR = ? ", 1, compCode, transfer.REPORTTYPE_1, reportYear).Desc("ID").Find(&results)
	return results, err
}

//GetCompInfoByCompCode 根据compCode获取机构资料信息
func (mdb *db) GetCompInfoByCompCode(compCode string) ([]*domain.TQ_COMP_INFO, error) {
	var results []*domain.TQ_COMP_INFO
	err := mdb.db.NewSession().Where("ISVALID = ? and COMPCODE = ?", 1, compCode).Find(&results)
	return results, err
}

//GetSkDailyPrices4DataChange 根据Secode和tradeDate获取股票历史日交易信息
func (mdb *db) GetSkDailyPrices4DataChange(seCode string, tradeDate string) ([]*domain.TQ_QT_SKDAILYPRICE, error) {
	var results []*domain.TQ_QT_SKDAILYPRICE
	err := mdb.db.NewSession().Where("ISVALID=? and TRADEDATE = ? and SECODE = ?", 1, tradeDate, seCode).Desc("ID").Find(&results)
	return results, err
}

//GetTqSkShareHolderNumByCompCodeAndEndDate 根据compCode和截止日期获取股东户数统计数据
func (mdb *db) GetTqSkShareHolderNumByCompCodeAndEndDate(compCode string, endDate string) ([]*domain.TQ_SK_SHAREHOLDERNUM, error) {
	var results []*domain.TQ_SK_SHAREHOLDERNUM
	err := mdb.db.NewSession().Where("ISVALID = ? and COMPCODE = ? and ENDDATE=?", 1, compCode, endDate).Find(&results)
	return results, err
}

//GetShareStruChgByCompCodeAndPublishDate 根据compCode和信息发布日期取得股本结构变化信息
func (mdb *db) GetShareStruChgByCompCodeAndPublishDate(compCode string, publishDate string) (*domain.TQ_SK_SHARESTRUCHG, error) {
	var results []*domain.TQ_SK_SHARESTRUCHG
	err := mdb.db.NewSession().Where("ISVALID=?  and COMPCODE = ? and PUBLISHDATE = ?", 1, compCode, publishDate).Desc("ID").Find(&results)
	if err != nil {
		return nil, err
	}
	if len(results) > 0 {
		return results[0], nil
	}
	return nil, nil
}

// GetTqSkShareHolderByCompCodeAndPublishDate 根据compCode和信息发布日期，获取股东名单列表
func (mdb *db) GetTqSkShareHolderByCompCodeAndPublishDate(compCode string, publishDate string) ([]*domain.TQ_SK_SHAREHOLDER, error) {
	var results []*domain.TQ_SK_SHAREHOLDER
	err := mdb.db.NewSession().Where("ISVALID = ? and COMPCODE = ? and publishDate=?", 1, compCode, publishDate).Find(&results)
	return results, err
}

//最新指标使用
func (mdb *db) GetPrgFinMainIndexByCompCodeAndEndDate(compCode string, endDate string) ([]*domain.TQ_FIN_PRGFINMAININDEX, error) {
	var results []*domain.TQ_FIN_PRGFINMAININDEX
	err := mdb.db.NewSession().Where("ISVALID=? and REPORTTYPE = ? and COMPCODE = ? and ENDDATE = ?", 1, transfer.REPORTTYPE_1, compCode, endDate).Asc("REPORTYEAR").Find(&results)
	return results, err
}

//GetPrgIncStatementNewByCompCodeAndEndDate 取得财务数据： 根据 compCode 取得  一般企业利润表(新准则产品表)
func (mdb *db) GetPrgIncStatementNewByCompCodeAndEndDate(compCode string, endDate string) ([]*domain.TQ_FIN_PRGINCSTATEMENTNEW, error) {
	var results []*domain.TQ_FIN_PRGINCSTATEMENTNEW
	err := mdb.db.NewSession().Where("ISVALID=? and REPORTTYPE = ? and COMPCODE = ? and ENDDATE = ?", 1, transfer.REPORTTYPE_1, compCode, endDate).Asc("REPORTYEAR").Find(&results)
	return results, err
}

//GetPrgIndicDataByCompCodeAndEndDate 财务数据-主要指标：根据 compCode 取得 衍生财务指标(产品表)信息
func (mdb *db) GetPrgIndicDataByCompCodeAndEndDate(compCode string, endDate string) ([]*domain.TQ_FIN_PRGINDICDATA, error) {
	var results []*domain.TQ_FIN_PRGINDICDATA
	err := mdb.db.NewSession().Where("ISVALID=? and (REPORTTYPE = ? or REPORTTYPE = ?) and  COMPCODE = ? and ENDDATE = ? ", 1, transfer.REPORTTYPE_1, transfer.REPORTTYPE_c3, compCode, endDate).Asc("REPORTYEAR").Find(&results)
	return results, err
}

//GetPrgIndicDataSubByCompCodeAndEndDate 财务数据-主要指标：根据 compCode 取得 衍生财务指标副表(产品表) 数据
func (mdb *db) GetPrgIndicDataSubByCompCodeAndEndDate(compCode string, endDate string) ([]*domain.TQ_FIN_PRGINDICDATASUB, error) {
	var results []*domain.TQ_FIN_PRGINDICDATASUB
	err := mdb.db.NewSession().Where("ISVALID=? and REPORTTYPE = ? and COMPCODE = ? and ENDDATE = ?  ", 1, transfer.REPORTTYPE_c3, compCode, endDate).Asc("REPORTYEAR").Find(&results)
	return results, err
}

func (mdb *db) GetTqFinPrgFinMainIndexByBizKey(compCode string, endDate string, reportDateType string) (*domain.TQ_FIN_PRGFINMAININDEX, error) {
	var results []*domain.TQ_FIN_PRGFINMAININDEX
	err := mdb.db.NewSession().Where("ISVALID=? and REPORTDATETYPE = ? and COMPCODE = ? and ENDDATE = ?", 1, reportDateType, compCode, endDate).Desc("ID").Find(&results)
	if err != nil {
		return nil, err
	}
	if len(results) > 0 {
		return results[0], nil
	} else {
		return nil, nil
	}
}
func (mdb *db) GetTqFinPrgIndicDataByBizKey(compCode string, endDate string, reportDateType string) (*domain.TQ_FIN_PRGINDICDATA, error) {
	var results []*domain.TQ_FIN_PRGINDICDATA
	err := mdb.db.NewSession().Where("ISVALID=? and REPORTDATETYPE = ?  and  COMPCODE = ? and ENDDATE = ? ", 1, reportDateType, compCode, endDate).Desc("ID").Find(&results)
	if err != nil {
		return nil, err
	}
	if len(results) > 0 {
		return results[0], nil
	} else {
		return nil, nil
	}
}
func (mdb *db) GetTqFinPrgIndicDataSubByBizKey(compCode string, endDate string, reportDateType string) (*domain.TQ_FIN_PRGINDICDATASUB, error) {
	var results []*domain.TQ_FIN_PRGINDICDATASUB
	err := mdb.db.NewSession().Where("ISVALID=? and REPORTDATETYPE = ? and COMPCODE = ? and ENDDATE = ?  ", 1, reportDateType, compCode, endDate).Desc("ID").Find(&results)
	if err != nil {
		return nil, err
	}
	if len(results) > 0 {
		return results[0], nil
	} else {
		return nil, nil
	}
}

//GetTqFinPrgPasqSubjects 获取单季衍生利润科目(产品表）信息
func (mdb *db) GetTqFinPrgPasqSubjects(compCode string, endDate string, reportType string) (*domain.TQ_FIN_PRGPASQSUBJECTS, error) {
	var results []*domain.TQ_FIN_PRGPASQSUBJECTS
	var err error

	if reportType != "" {
		err = mdb.db.NewSession().Where("ISVALID=? and (REPORTTYPE = ? or REPORTTYPE = ?) and  COMPCODE = ? and ENDDATE = ? ", 1, transfer.REPORTTYPE_1, transfer.REPORTTYPE_c3, compCode, endDate).Desc("ID").Find(&results)
	} else {
		err = mdb.db.NewSession().Where("ISVALID=? and  REPORTTYPE = ? and  COMPCODE = ? and ENDDATE = ? ", 1, reportType, compCode, endDate).Desc("ID").Find(&results)

	}
	if err != nil {
		return nil, err
	}
	if len(results) > 0 {
		return results[0], nil
	} else {
		return nil, nil
	}
}

//GetTqFinProQinDic 获取单季衍生指标（产品表）信息
func (mdb *db) GetTqFinProQinDic(compCode string, endDate string, reportType string) (*domain.TQ_FIN_PROQINDIC, error) {
	var results []*domain.TQ_FIN_PROQINDIC
	var err error

	if reportType != "" {
		err = mdb.db.NewSession().Where("ISVALID=? and (REPORTTYPE = ? or REPORTTYPE = ?) and  COMPCODE = ? and ENDDATE = ? ", 1, transfer.REPORTTYPE_1, transfer.REPORTTYPE_c3, compCode, endDate).Desc("ID").Find(&results)
	} else {
		err = mdb.db.NewSession().Where("ISVALID=? and  REPORTTYPE = ? and  COMPCODE = ? and ENDDATE = ? ", 1, reportType, compCode, endDate).Desc("ID").Find(&results)

	}
	if err != nil {
		return nil, err
	}
	if len(results) > 0 {
		return results[0], nil
	} else {
		return nil, nil
	}
}

func (mdb *db) GetTqSkFundamentalsBySymbolAndEndDate(symbol string, endDate string) ([]*domain.TQ_SK_FUNDAMENTALS, error) {
	var results []*domain.TQ_SK_FUNDAMENTALS
	err := mdb.db.NewSession().Where("ISVALID = ? and RIGHT(SECODE,6)  = ? and ENDDATE = ?", 1, symbol, endDate).Desc("ID").Find(&results)
	return results, err
}

//GetTqFinPrgbincstatementnewByCompCodeAndDate 根据业务主键获取银行利润表信息
func (mdb *db) GetTqFinPrgbincstatementnewByCompCodeAndDate(compCode string, endDate string, reportYear string, reportDateType string) (*domain.TQ_FIN_PRGBINCSTATEMENTNEW, error) {
	var results []*domain.TQ_FIN_PRGBINCSTATEMENTNEW
	err := mdb.db.NewSession().Where("ISVALID=? and REPORTTYPE = ? and COMPCODE = ? and ENDDATE = ? and REPORTYEAR = ? and REPORTDATETYPE = ?", 1, transfer.REPORTTYPE_1, compCode, endDate, reportYear, reportDateType).Desc("REPORTYEAR").Find(&results)
	if err != nil {
		return nil, err
	}
	if len(results) > 0 {
		return results[0], nil
	}
	return nil, nil
}

//GetPrgIncStatementNewByBizKey 根据业务主键查询一般企业利润信息
func (mdb *db) GetPrgIncStatementNewByBizKey(compCode string, endDate string, reportYear string, reportDateType string) (*domain.TQ_FIN_PRGINCSTATEMENTNEW, error) {
	var results []*domain.TQ_FIN_PRGINCSTATEMENTNEW
	err := mdb.db.NewSession().Where("ISVALID=? and REPORTTYPE = ? and COMPCODE = ? and ENDDATE = ? and REPORTYEAR = ? and REPORTDATETYPE = ?", 1, transfer.REPORTTYPE_1, compCode, endDate, reportYear, reportDateType).Desc("REPORTYEAR").Find(&results)
	if err != nil {
		return nil, err
	}
	if len(results) > 0 {
		return results[0], nil
	}
	return nil, nil
}
